Lifecycle LiveData与ViewModel

Lifecycle使用

它是Google官方发布的一个处理Activity和Fragment声明周期的框架,之前我们处理生命周期都是在类里面做处理。如下这种方式本身是没有任何问题的,但是如果类或者逻辑一多,这种处理声明周期的逻辑就会很多了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Override
protected void onStart() {
super.onStart();
//处理onStart
p层.xx
}

@Override
protected void onResume() {
super.onResume();
//处理onResume
p层.xx
}

@Override
protected void onDestroy() {
super.onDestroy();
}

有没有什么办法让Presenter或者一些其他需要感知act或者fgt自动感知,这样就可以解耦这种在生命周期调用方法的情况了。

通过Lifecycle解决这个问题

AppCompatActivity中提供了一个getLifecycle方法,通过addObserver() 就加入一个生命周期观察对象,如果当前activity变更了生命周期,ClickListener中的监听方法也会被调用。

ClickListener类实现了LifecycleObserver接口,表示这个类需要感知生命周期,通过@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)注解来注解对应的生命周期方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

public class MainActivity extends AppCompatActivity {


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ClickListener clickListener = new ClickListener(getLifecycle());
getLifecycle().addObserver(clickListener);
}

@Override
protected void onStart() {
super.onStart();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class ClickListener implements LifecycleObserver {
Lifecycle mLif;

public ClickListener(Lifecycle lifecycle) {
mLif = lifecycle;
}

@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
void onResume() {
Log.i("jinwei", "onResume=" + mLif.getCurrentState());

}

@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
void onCreate() {
Log.i("jinwei", "onCreate");
}

@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void onStop() {
Log.i("jinwei", "onStop");
}

@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
void onDestroy() {
Log.i("jinwei", "onDestroy");
if (mLif.getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
Log.i("jinwei", "***************");
}

}

@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
void onPause() {
Log.i("jinwei", "onPause");
}

@OnLifecycleEvent(Lifecycle.Event.ON_START)
void onStart() {
Log.i("jinwei", "onStart");
}

}

我们也可以通过实现LifecycleOwner接口实现一个自己的Lifecycle。重点是我们创建了一个LifecycleRegistry类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MainActivity extends AppCompatActivity implements LifecycleOwner {

LifecycleRegistry registry;

@Override
public Lifecycle getLifecycle() {
return registry;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
registry = new LifecycleRegistry(this);
ClickListener clickListener = new ClickListener(getLifecycle());
getLifecycle().addObserver(clickListener);
setContentView(R.layout.activity_main);

}

Lifecycle解决的问题

降低代码耦合,可以观察act和fgt的生命周期,实现自动监听,不需要手动在act和fgt中去调用,简化了代码增加了可维护的程度。

LiveData和ViewModel

我们开发中经常会有一个这样的问题,我们的一些请求网络的逻辑代码,或者操作数据层的代码都会写在activity层中。有可能经常有一个Activity类几千行代码。

ViewModel

ViewModel就是解决这个问题的,它的唯一作用和概念就是它只做数据层面的操作,比如网络请求,比如数据库操作。这些操作都可以放在ViewModel中,当我们项目的代码一大的时候就可以看到它的好处了。当然光是这样还不能满足我的期望,这个时候LiveData就上场了。

LiveData

LiveData是一个抽象的数据类,它的主要作用是提供通知给View层做数据刷新。通过LiveData包装的数据类,只要数据集一变更,监听通知的地方就会自动收到数据刷新的回调。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class NameViewModel : ViewModel() {


var name: MutableLiveData<String>? = MutableLiveData()


/**
* 宿主销毁后调用的,可以做一些清除数据的操作。
*/
override fun onCleared() {
super.onCleared()
name = null;
Log.i("jinwei", "onCleared");
}


//可以做网络请求
fun loadData() {
name?.value = "我是测试数据"
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class MainActivity extends AppCompatActivity {


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NameViewModel model = ViewModelProviders.of(this).get(NameViewModel.class);
model.getName().observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
Log.i("jinwei","onChanged s =" +s);
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG);
TextView text = findViewById(R.id.text);
text.setText(s);
}
});
model.loadData();
}


}

LiveData的observe方法就是监听一个数据更新通知。

声明周期

ViewModel的声明周期依赖于Activiy或者Fragment,会在onCreate的时候创建ViewModel,ViewModel的生命周期一直持续到Activity最终销毁或Frament最终detached,期间由于屏幕旋转等配置变化引起的Activity销毁重建并不会导致ViewModel重建

image

初始化通过如下方式

1
NameViewModel model = ViewModelProviders.of(this).get(NameViewModel.class);

this参数一般为Activity或Fragment,因此ViewModelProvider可以获取组件的生命周期。

Activity在生命周期中可能会触发多次onCreate(),而ViewModel则只会在第一次onCreate()时创建,然后直到最后Activity销毁。